import { onMounted, ref, watch } from "vue";
import { ValidateTool } from "@webxue/common";

/**
 * form表单通用逻辑封装
 * */
export default function useForm(option: UseFormInfoOption) {

  // 表单组件Ref
  const formRef = ref<any>();

  // 表单数据响应式
  const formState = ref<Record<string, any>>(option.formState);

  // 详情数据
  const detailInfo = ref<Record<string, any>>({});

  // 校验失败字段集合
  const errorFields = ref<any[]>([]);

  // 表单校验
  const onValidateFields = () => {
    formRef.value?.aformRef
      ?.validateFields()
      ?.then(async (values: Record<string, any>) => {
        option.onValidateSuccess(values);
      })
      ?.catch((error: any) => {
        errorFields.value = error.errorFields || [];
      });
  };

  /**
   * 通用表单项校验规则
   * @param {keyof FormRulesData} fieldName - 校验字段名
   * */
  const getFormRules = (fieldName?: keyof FormRulesData) => {
    const formRules: FormRulesData = {
      mobile: [
        {
          required: true,
          trigger: "change",
          validator: () => {
            const value = formState.value[fieldName];
            if (!value) return Promise.reject("请输入手机号");
            if (!ValidateTool.isPhone(value)) return Promise.reject("请输入合法的手机号");
            return Promise.resolve();
          }
        }
      ]
    };
    if (fieldName && formRules[fieldName]) return formRules[fieldName];
    return formRules;
  };

  // 当表单项内容发生改变时，重新校验曾经校验失败的表单项
  watch(
    () => formState.value,
    () => {
      for (const err of errorFields.value) {
        formRef.value?.aformRef?.validateFields(err.name);
      }
    },
    { deep: true }
  );

  // 挂载完成请求数据
  onMounted(async () => {
    const response = await option.onInit();
    detailInfo.value = response.data;
  });

  return { detailInfo, formState, formRef, onValidateFields, getFormRules };
}

// 获取表单详情入参
export interface UseFormInfoOption {
  // 表单项
  formState: Record<string, any>;
  // 获取详情
  onInit: () => Promise<any>;
  // 表单校验成功回调
  onValidateSuccess: (values: Record<string, any>) => void;
}

// 表单项校验规则集合
declare interface FormRulesData {
  mobile: any[];
}
